package service

import (
	"encoding/json"
	"fmt"
	"log"
	"math/rand"
	"strconv"
	"strings"
	"time"

	"github.com/slrun/callcenter/internal/model"
	"github.com/slrun/callcenter/internal/pkg/freeswitch"
)

// IVREngine IVR流程引擎
type IVREngine struct {
	fsClient       *freeswitch.Client
	flows          map[string]*model.IVRFlow
	sessions       map[string]*model.IVRSession
	prompts        map[string]*model.IVRPrompt
	actionHandlers map[model.IVRActionType]ActionHandler
}

// ActionHandler 动作处理器类型
type ActionHandler func(*model.IVRSession, *model.IVRAction, *IVREngine) error

// NewIVREngine 创建IVR引擎
func NewIVREngine(fsClient *freeswitch.Client) *IVREngine {
	engine := &IVREngine{
		fsClient:       fsClient,
		flows:          make(map[string]*model.IVRFlow),
		sessions:       make(map[string]*model.IVRSession),
		prompts:        make(map[string]*model.IVRPrompt),
		actionHandlers: make(map[model.IVRActionType]ActionHandler),
	}

	// 注册动作处理器
	engine.registerActionHandlers()

	return engine
}

// 注册动作处理器
func (e *IVREngine) registerActionHandlers() {
	e.actionHandlers[model.IVRActionPlay] = e.handlePlayAction
	e.actionHandlers[model.IVRActionMenu] = e.handleMenuAction
	e.actionHandlers[model.IVRActionTransfer] = e.handleTransferAction
	e.actionHandlers[model.IVRActionHangup] = e.handleHangupAction
	e.actionHandlers[model.IVRActionRecord] = e.handleRecordAction
	e.actionHandlers[model.IVRActionSetVar] = e.handleSetVarAction
	e.actionHandlers[model.IVRActionGoto] = e.handleGotoAction
	e.actionHandlers[model.IVRActionWait] = e.handleWaitAction
}

// 动作处理器实现
func (e *IVREngine) handlePlayAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	// 获取要播放的文件
	filePath, exists := action.Params["file_path"]
	if !exists {
		return fmt.Errorf("missing file_path parameter")
	}

	// 通过FreeSWITCH播放文件
	if e.fsClient != nil {
		cmd := fmt.Sprintf("uuid_broadcast %s %s both", session.CallUUID, filePath)
		_, err := e.fsClient.SendAPI(cmd)
		if err != nil {
			return fmt.Errorf("failed to play file: %w", err)
		}
	}

	// 添加到历史
	e.addHistory(session, string(action.Type), filePath)

	// 执行完后跳转到下一个节点
	return nil
}

func (e *IVREngine) handleMenuAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	// 播放菜单提示
	if prompt, exists := action.Params["prompt"]; exists && prompt != "" {
		if e.fsClient != nil {
			cmd := fmt.Sprintf("uuid_broadcast %s %s both", session.CallUUID, prompt)
			_, err := e.fsClient.SendAPI(cmd)
			if err != nil {
				log.Printf("Failed to play menu prompt: %v", err)
			}
		}
	}

	// 注意：菜单处理是异步的，需要等待用户输入
	// 这里只是设置会话状态，实际处理会在收到DTMF时进行
	session.Variables["current_menu"] = "menu"
	e.addHistory(session, string(action.Type), "Waiting for input")

	return nil
}

func (e *IVREngine) handleTransferAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	destination, exists := action.Params["destination"]
	if !exists {
		return fmt.Errorf("missing destination parameter")
	}

	// 通过FreeSWITCH转接呼叫
	if e.fsClient != nil {
		err := e.fsClient.TransferCall(session.CallUUID, destination)
		if err != nil {
			return fmt.Errorf("failed to transfer call: %w", err)
		}
	}

	e.addHistory(session, string(action.Type), destination)
	return nil
}

func (e *IVREngine) handleHangupAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	// 通过FreeSWITCH挂断呼叫
	if e.fsClient != nil {
		err := e.fsClient.HangupCall(session.CallUUID)
		if err != nil {
			log.Printf("Failed to hangup call: %v", err)
		}
	}

	e.addHistory(session, string(action.Type), "Call terminated")
	return nil
}

func (e *IVREngine) handleRecordAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	// 获取录音参数
	durationStr := action.Params["duration"]
	duration := 30 // 默认30秒
	if durationStr != "" {
		if d, err := strconv.Atoi(durationStr); err == nil {
			duration = d
		}
	}

	// 生成录音文件名
	filename := fmt.Sprintf("ivr_record_%s_%s", session.CallUUID, time.Now().Format("20060102_150405"))

	// 开始录音
	if e.fsClient != nil {
		err := e.fsClient.RecordCall(session.CallUUID, filename, "wav")
		if err != nil {
			return fmt.Errorf("failed to start recording: %w", err)
		}

		// 设置定时器停止录音
		go func() {
			time.Sleep(time.Duration(duration) * time.Second)
			e.fsClient.StopRecording(session.CallUUID)
			session.Variables["last_recording"] = filename + ".wav"
		}()
	}

	e.addHistory(session, string(action.Type), filename)
	return nil
}

func (e *IVREngine) handleSetVarAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	// 设置变量
	for key, value := range action.Params {
		session.Variables[key] = value
	}

	e.addHistory(session, string(action.Type), "Variables set")
	return nil
}

func (e *IVREngine) handleGotoAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	targetNode, exists := action.Params["target"]
	if !exists {
		return fmt.Errorf("missing target parameter")
	}

	// 更新当前节点
	session.CurrentNode = targetNode
	e.addHistory(session, string(action.Type), targetNode)

	return nil
}

func (e *IVREngine) handleWaitAction(session *model.IVRSession, action *model.IVRAction, engine *IVREngine) error {
	// 获取等待时间
	waitStr := action.Params["seconds"]
	waitSeconds := 1 // 默认1秒
	if waitStr != "" {
		if w, err := strconv.Atoi(waitStr); err == nil {
			waitSeconds = w
		}
	}

	// 等待指定时间
	time.Sleep(time.Duration(waitSeconds) * time.Second)
	e.addHistory(session, string(action.Type), fmt.Sprintf("Waited %d seconds", waitSeconds))

	return nil
}

// 辅助方法
func (e *IVREngine) addHistory(session *model.IVRSession, action string, details string) {
	history := model.IVRSessionHistory{
		NodeID:    session.CurrentNode,
		Action:    action,
		Input:     details,
		Timestamp: time.Now(),
	}
	session.History = append(session.History, history)
	session.UpdatedAt = time.Now()
}

// 注意：不能为非本地类型定义方法，已移除String和ID方法的定义

// 核心功能方法

// RegisterFlow 注册IVR流程
func (e *IVREngine) RegisterFlow(flow *model.IVRFlow) {
	e.flows[flow.ID] = flow
}

// StartSession 开始IVR会话
func (e *IVREngine) StartSession(flowID, callUUID, callerID string) (*model.IVRSession, error) {
	flow, exists := e.flows[flowID]
	if !exists {
		return nil, fmt.Errorf("IVR flow not found: %s", flowID)
	}

	// 创建会话
	session := &model.IVRSession{
		ID:          fmt.Sprintf("session_%s_%d", callUUID, rand.Intn(10000)),
		FlowID:      flowID,
		CallUUID:    callUUID,
		CallerID:    callerID,
		CurrentNode: flow.EntryNodeID,
		Variables:   make(map[string]string),
		History:     make([]model.IVRSessionHistory, 0),
		CreatedAt:   time.Now(),
		UpdatedAt:   time.Now(),
	}

	e.sessions[session.ID] = session
	log.Printf("Started IVR session: %s for flow: %s", session.ID, flowID)

	// 立即执行入口节点
	go e.ExecuteNode(session, flow.EntryNodeID)

	return session, nil
}

// ExecuteNode 执行IVR节点
func (e *IVREngine) ExecuteNode(session *model.IVRSession, nodeID string) error {
	// 获取流程
	flow, exists := e.flows[session.FlowID]
	if !exists {
		return fmt.Errorf("flow not found: %s", session.FlowID)
	}

	// 查找节点
	var node *model.IVRNode
	for i := range flow.Nodes {
		if flow.Nodes[i].ID == nodeID {
			node = &flow.Nodes[i]
			break
		}
	}

	if node == nil {
		return fmt.Errorf("node not found: %s", nodeID)
	}

	// 更新当前节点
	session.CurrentNode = nodeID

	// 检查条件
	if node.Condition != "" {
		// 这里可以实现条件表达式的评估
		// 简单示例，实际实现可能需要更复杂的表达式解析器
		if !e.evaluateCondition(node.Condition, session.Variables) {
			// 条件不满足，查找下一个默认节点或结束
			nextNode := e.findDefaultNextNode(flow, nodeID)
			if nextNode != "" {
				return e.ExecuteNode(session, nextNode)
			}
			return nil
		}
	}

	// 获取动作处理器
	handler, exists := e.actionHandlers[node.Action.Type]
	if !exists {
		return fmt.Errorf("no handler for action type: %s", node.Action.Type)
	}

	// 执行动作
	err := handler(session, &node.Action, e)
	if err != nil {
		return fmt.Errorf("failed to execute action: %w", err)
	}

	// 对于非菜单类动作，自动执行下一个节点
	if node.Action.Type != model.IVRActionMenu {
		nextNode := node.Action.NextNode
		if nextNode == "" {
			nextNode = e.findDefaultNextNode(flow, nodeID)
		}

		if nextNode != "" {
			// 短暂延迟后执行下一个节点
			time.AfterFunc(500*time.Millisecond, func() {
				e.ExecuteNode(session, nextNode)
			})
		}
	}

	return nil
}

// HandleDTMF 处理DTMF输入
func (e *IVREngine) HandleDTMF(callUUID, digits string) error {
	// 查找会话
	var session *model.IVRSession
	for _, s := range e.sessions {
		if s.CallUUID == callUUID {
			session = s
			break
		}
	}

	if session == nil {
		return fmt.Errorf("no active IVR session for call: %s", callUUID)
	}

	// 获取当前流程
	flow, exists := e.flows[session.FlowID]
	if !exists {
		return fmt.Errorf("flow not found: %s", session.FlowID)
	}

	// 获取当前节点
	var currentNode *model.IVRNode
	for i := range flow.Nodes {
		if flow.Nodes[i].ID == session.CurrentNode {
			currentNode = &flow.Nodes[i]
			break
		}
	}

	if currentNode == nil {
		return fmt.Errorf("current node not found: %s", session.CurrentNode)
	}

	// 查找菜单选项
	target := ""
	for _, option := range currentNode.Action.MenuOptions {
		if option.Key == digits {
			switch option.Action {
			case "transfer":
				// 转接
				return e.handleTransferAction(session, &model.IVRAction{
					Type: model.IVRActionTransfer,
					Params: map[string]string{
						"destination": option.Target,
					},
				}, e)
			case "node":
				// 跳转到节点
				target = option.Target
			}
			break
		}
	}

	// 记录用户输入
	e.addHistory(session, "DTMF", digits)

	// 如果有目标节点，执行它
	if target != "" {
		return e.ExecuteNode(session, target)
	}

	// 如果没有匹配的选项，可以播放错误提示
	if invalidPrompt, exists := currentNode.Action.Params["invalid_option_prompt"]; exists {
		if e.fsClient != nil {
			cmd := fmt.Sprintf("uuid_broadcast %s %s both", session.CallUUID, invalidPrompt)
			e.fsClient.SendAPI(cmd)
		}
	}

	// 重新执行当前节点
	return e.ExecuteNode(session, session.CurrentNode)
}

// GetSession 获取会话
func (e *IVREngine) GetSession(sessionID string) (*model.IVRSession, error) {
	session, exists := e.sessions[sessionID]
	if !exists {
		return nil, fmt.Errorf("session not found: %s", sessionID)
	}
	return session, nil
}

// EndSession 结束会话
func (e *IVREngine) EndSession(sessionID string) error {
	_, exists := e.sessions[sessionID]
	if !exists {
		return fmt.Errorf("session not found: %s", sessionID)
	}

	delete(e.sessions, sessionID)
	log.Printf("Ended IVR session: %s", sessionID)
	return nil
}

// LoadFlowFromJSON 从JSON加载IVR流程
func (e *IVREngine) LoadFlowFromJSON(jsonStr string) (*model.IVRFlow, error) {
	var flow model.IVRFlow
	err := json.Unmarshal([]byte(jsonStr), &flow)
	if err != nil {
		return nil, fmt.Errorf("failed to parse flow JSON: %w", err)
	}

	e.RegisterFlow(&flow)
	return &flow, nil
}

// 辅助方法
func (e *IVREngine) evaluateCondition(condition string, variables map[string]string) bool {
	// 简单条件评估，实际实现可能需要更复杂的表达式解析器
	// 示例：var1 == "value1"
	parts := strings.Split(condition, "==")
	if len(parts) != 2 {
		return false
	}

	varName := strings.TrimSpace(parts[0])
	varValue := strings.TrimSpace(parts[1])
	varValue = strings.Trim(varValue, "\"")

	actualValue, exists := variables[varName]
	return exists && actualValue == varValue
}

func (e *IVREngine) findDefaultNextNode(flow *model.IVRFlow, currentNodeID string) string {
	// 简单实现：查找下一个节点ID
	// 实际实现可能需要更复杂的逻辑，如基于流程定义的连接关系
	for i, node := range flow.Nodes {
		if node.ID == currentNodeID && i+1 < len(flow.Nodes) {
			return flow.Nodes[i+1].ID
		}
	}
	return "" // 没有找到下一个节点
}
